<template>
  <div class="chat-container">
    <div class="chat-top">
      <div class="chat-content" v-for="chat in chatList" :key="chat.id">
        <div>
          <p>
            {{ chat.req }}
          </p>
        </div>
        <div>
          <img class="logo-pic" src="../../assets/J-logo.webp" alt="" />
          <MdPreview
            v-model="chat.res"
            editorId="show"
            :theme="'light'"
          ></MdPreview>
        </div>
      </div>
      <div class="chat-content" v-show="question">
        <div>
          <p>
            {{ question }}
          </p>
        </div>
        <div>
          <img class="logo-pic" src="../../assets/J-logo.webp" alt="" />
          <div class="gen-ing">
            <span>正</span><span>在</span><span>生</span><span>成</span
            ><span>中</span><span>.</span><span>.</span><span>.</span>
          </div>
          <div id="chattop" v-loading="loading">
            <MdPreview
              v-model="answerText"
              editorId="chating"
              :theme="'light'"
            ></MdPreview>
          </div>
        </div>
      </div>
    </div>
    <div class="input-area">
      <div class="input-left">
        <div
          ref="inputCommentRef"
          contenteditable="true"
          class="comment-content input-inputText"
          :rows="3"
          :cols="20"
          @keydown.enter.prevent="enterQuestion"
          @input="inputComment"
          @focus="focusComment"
          @blur="blurComment"
          @click="blurComment"
          @paste="handlePaste"
          :placeholder="placeholder"
        ></div>
      </div>
      <div class="input-right">
        <div v-if="isChating" style="background-color: #dcdcdc;" @click="pause = true">
          <el-tooltip
            class="box-item"
            effect="dark"
            content="停止生成"
            placement="top"
          >
            <button></button>
          </el-tooltip>
        </div>
        <div v-else>
          <el-tooltip
            class="box-item"
            effect="dark"
            content="开始生成"
            placement="top"
          >
            <img
              src="../../assets/svg/send.svg"
              alt="sentMessageToAi"
              :style="{ '--cursor': inputValue ? 'pointer' : 'not-allowed' }"
              @click="sentToAi"
            />
          </el-tooltip>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, nextTick } from "vue";
import { debounce, BaseUrl } from "@/utils/tools";
import { MdPreview } from "md-editor-v3";
import "md-editor-v3/lib/style.css";

interface Chat {
  id: string;
  req: string;
  res: string;
}

const inputCommentRef = ref<HTMLDivElement | null>(null);
const inputValue = ref<string>("");
const showPublish = ref<boolean>(false);
const currentIndex = ref<number>(0);
const placeholder = ref<string>("不懂就问ChatJPT");
const question = ref<string>(""); // 问题
const answerText = ref<string>(""); // 回答
const loading = ref<boolean>(false);
const isChating = ref<boolean>(false);
const chatList = ref<Chat[]>([]); // 聊天记录

const pause = ref<boolean>(false); // 停止生成

function updateText() {
  // inputValue.value = inputCommentRef.value?.innerHTML || "";
  const innerHTML = inputCommentRef.value?.innerHTML || "";
  // 去掉最后一个空格符
  inputValue.value =
    innerHTML === "<br>" ? "" : innerHTML.replace(/&nbsp;([^&nbsp;]*)$/, "$1");
  console.log(inputValue.value);
}
const inputComment = debounce(updateText, 100);
// 鼠标聚焦
const focusComment = () => {
  showPublish.value = true;
};

const blurComment = () => {
  currentIndex.value = getCurrentIndex();
};

const getCurrentIndex = () => {
  var range: any;
  if ((window as Window).getSelection) {
    //ie11 10 9 ff safari
    range = window.getSelection(); //创建range
    return range.focusOffset;
  } else if ((document as any).selection) {
    range = (document as any).selection.createRange(); //创建选择对象
    return range.focusOffset;
  }
};
const sentToAi = async () => {
  if (isChating.value) {
    placeholder.value = "不懂就问ChatJPT";
    chatList.value.push({
      id: new Date().getTime() + "",
      req: question.value,
      res: answerText.value,
    });
    isChating.value = false;
    inputCommentRef.value?.innerHTML
      ? (inputCommentRef.value.innerHTML = "")
      : "";
    question.value = "";
    answerText.value = "";
    inputValue.value = "";
    return;
  }
  if (!inputValue.value) {
    return;
  }
  isChating.value = true;
  inputCommentRef.value?.innerHTML
    ? (inputCommentRef.value.innerHTML = "")
    : "";
  question.value = inputValue.value.replace(/\s|&nbsp;/g, " ");
  inputValue.value = "";
  answerText.value = "";
  loading.value = true;
  placeholder.value = "正在生成中......";
  sendMessageToServer(question.value);
  await nextTick();
  focusChating();
};

const handlePaste = (event: ClipboardEvent) => {
  event.preventDefault();
  const text = event.clipboardData?.getData("text/plain");
  if (text) {
    // 在粘贴时插入纯文本内容
    document.execCommand("insertText", false, text);
  }
};

const enterQuestion = (event: any) => {
  if (event.keyCode === 13) {
    sentToAi();
    event.stopPropagation();
  }
};

const sendMessageToServer = (message: any) => {
  const url = BaseUrl + "apis/getOpenAi" + "/" + message;
  const eventSource: any = new EventSource(url);

  eventSource.onmessage = function (event: any) {
    if (event.data === "done:true" || pause.value) {
      pause.value ? (pause.value = false) : "";
      eventSource.close();
      placeholder.value = "不懂就问ChatJPT";
      chatList.value.push({
        id: new Date().getTime() + "",
        req: question.value,
        res: answerText.value,
      });
      isChating.value = false;
      inputCommentRef.value?.innerHTML
        ? (inputCommentRef.value.innerHTML = "")
        : "";
      question.value = "";
      answerText.value = "";
      inputValue.value = "";
      focusChating();
      return;
    }
    answerText.value += event.data;
    focusChating();
  };

  eventSource.onopen = function (event: Event) {
    loading.value = false;
  };

  eventSource.onerror = function (event: Event) {
    pause.value ? (pause.value = false) : "";
    loading.value = false;
    eventSource.close();
    placeholder.value = "不懂就问ChatJPT";
    chatList.value.push({
      id: new Date().getTime() + "",
      req: question.value,
      res: "生成失败,请重试",
    });
    isChating.value = false;
  };
};

const focusChating = () => {
  const dom = document.getElementById("chattop");
  dom?.scrollIntoView({
    behavior: "smooth", // 设置滚动行为为平滑滚动，这样过渡更自然，如果不需要平滑滚动可以去掉这个配置项
  });
};
</script>

<style lang="scss" scoped>
:deep(.show-preview-wrapper) {
  padding: 10px;
}
.chat-container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  height: calc(100vh - 178px);
  overflow-y: scroll;
  background-color: #ffffff;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  .chat-top {
    .chat-content:nth-child(1) {
      div:nth-child(1) {
        margin: 0 0 12px 0;
      }
    }
    .chat-content {
      word-wrap: break-word;
      div:nth-child(1) {
        margin: 12px 0;
        display: flex;
        align-items: center;
        justify-content: flex-end;
        p {
          background-color: #e0dfff;
          border-radius: 12px;
          padding: 12px;
        }
      }
      div:nth-child(2) {
        display: flex;
        flex-direction: column;
        position: relative;
        background-color: #ffffff;
        border-radius: 12px;
        img {
          width: 1.4rem;
          height: 1.4rem;
          border-radius: 50%;
          position: absolute;
          left: -1.4rem;
          top: 20px;
        }
        .gen-ing {
          display: flex;
          flex-direction: row;
          padding-top: 0;
          font-size: 1rem;
          color: pink;
          height: 1.4rem;
          padding-left: 10px;
          padding-top: 5px;
          span {
            display: inline-block;
            opacity: 0;
            animation: blink 1.4s infinite both;
          }

          span:nth-child(2) {
            animation-delay: 0.2s;
          }

          span:nth-child(3) {
            animation-delay: 0.4s;
          }

          span:nth-child(4) {
            animation-delay: 0.6s;
          }

          span:nth-child(5) {
            animation-delay: 0.8s;
          }

          span:nth-child(6) {
            animation-delay: 1s;
          }

          span:nth-child(7) {
            animation-delay: 1.2s;
          }

          span:nth-child(8) {
            animation-delay: 1.4s;
          }
        }
        p {
          min-height: 2rem;
        }
      }
    }
  }

  .input-area {
    position: fixed;
    bottom: 60px;
    background-color: #ffffff;
    height: fit-content;
    min-height: 58px;
    display: flex;
    justify-content: center;
    border-radius: 10px;
    box-shadow: 2px 4px 10px 0px rgba(0, 0, 0, 0.1);

    .input-left {
      height: auto;
      display: flex;
      flex: 1;
      width: 100%;

      :deep(.el-textarea__inner) {
        box-shadow: none;
      }
    }

    .input-right {
      @include flex();
      width: 40px;
      img {
        cursor: var(--cursor);
        border-radius: 50%;
      }
      div {
        // cursor: var(--cursor);
        width: 30px;
        height: 30px;
        border-radius: 50%;
        @include flex();
        button {
          width: 10px;
          height: 10px;
          background-color: red;
        }
      }
    }
  }
}

.input-inputText {
  width: 100%;
  padding: 12px;
  box-sizing: border-box;
  transition: all 0.3s;
  word-break: break-all;
  height: auto;
}

.comment-content:empty::before {
  content: attr(placeholder);
  color: #c1c1c1;
  font-size: 1rem;
}

@keyframes blink {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

@media screen and (max-width: 768px) {
  .chat-top {
    width: 100%;
    padding: 0.5rem;
  }
  .input-area {
    width: 100%;
  }
  .logo-pic {
    display: none;
  }
}

@media screen and (min-width: 768px) {
  .chat-top {
    width: 50%;
    padding: 1rem 3rem 0 3rem;
  }
  .input-area {
    width: 50%;
  }
}
</style>
